package cn.denvie.agent.common;

import javassist.CtMethod;
import javassist.NotFoundException;

/**
 * 代理方法Builder。
 *
 * @author DengZhaoyong
 * @version 1.0.0
 */
public class MethodBuilder {

    private String beginSrc;
    private String endSrc;
    private String errorSrc;

    public MethodBuilder setBeginSrc(String beginSrc) {
        this.beginSrc = beginSrc;
        return this;
    }

    public MethodBuilder setEndSrc(String endSrc) {
        this.endSrc = endSrc;
        return this;
    }

    public MethodBuilder setErrorSrc(String errorSrc) {
        this.errorSrc = errorSrc;
        return this;
    }

    public String buildSrc(CtMethod method) {
        try {
            String template = "void".equals(method.getReturnType().getName()) ? voidSource : source;
            String begin = beginSrc == null ? "" : beginSrc;
            String error = errorSrc == null ? "" : errorSrc;
            String end = endSrc == null ? "" : endSrc;
            return String.format(template, begin, method.getName(), error, end);
        } catch (NotFoundException e) {
            throw new AgentException(e);
        }
    }

    /**
     * 有返回值方法模板
     */
    final static String source = new StringBuilder().append("{\n")
            .append("%s")
            .append("        Object result = null;\n")
            .append("       try {\n")
            .append("            result = ($w)%s$Agent($$);\n")
            .append("        } catch (Throwable e) {\n")
            .append("%s")
            .append("            throw e;\n")
            .append("        } finally {\n")
            .append("%s")
            .append("        }\n")
            .append("        return ($r) result;\n")
            .append("}\n")
            .toString();

    /**
     * 无返回值方法模板
     */
    final static String voidSource = new StringBuilder().append("{\n")
            .append("%s")
            .append("        try {\n")
            .append("            %s$Agent($$);\n")
            .append("        } catch (Throwable e) {\n")
            .append("%s")
            .append("            throw e;\n")
            .append("        } finally {\n")
            .append("%s")
            .append("        }\n")
            .append("}\n")
            .toString();
}